package org.snw;

import java.util.concurrent.atomic.AtomicReference;

public class NodeSelector {

    private final AtomicReference<NodeWeightSet> nodeWeightListAtomicReference;

    public NodeSelector(NodeWeightSet nodeWeightSet) {
        this.nodeWeightListAtomicReference = new AtomicReference<>(nodeWeightSet);
    }

    public NodeWeight select() {
        NodeWeightSet nodeWeightSet = this.nodeWeightListAtomicReference.getAndUpdate(this::updateAndGetNodeWeightSet);
        NodeWeight system1 = nodeWeightSet.getSystem1();
        NodeWeight system2 = nodeWeightSet.getSystem2();
//        System.out.println(nodeWeightSet);
        if (system1.getCurWeight() > system2.getCurWeight()) {
//            System.out.println(system1);
            return system1;
        } else {
//            System.out.println(system2);
            return system2;
        }

    }

    private NodeWeight decreaseNodeWeight(NodeWeight nodeWeight) {
        return new NodeWeight(nodeWeight.getName(), nodeWeight.getWeight(), nodeWeight.getCurWeight() - 1);
    }

    private NodeWeight resetNodeWeight(NodeWeight nodeWeight) {
        return new NodeWeight(nodeWeight.getName(), nodeWeight.getWeight(), nodeWeight.getWeight());
    }

    private NodeWeightSet updateAndGetNodeWeightSet(NodeWeightSet nodeWeightSet) {
        NodeWeight system1 = nodeWeightSet.getSystem1();
        NodeWeight system2 = nodeWeightSet.getSystem2();
        NodeWeight maxSystem;
        NodeWeight minSystem;
        if (system1.getCurWeight() > system2.getCurWeight()) {
            maxSystem = system1;
            minSystem = system2;
        } else {
            maxSystem = system2;
            minSystem = system1;
        }
        NodeWeightSet newNodeWeightSet;
        if (maxSystem.getCurWeight() < 1) {
            newNodeWeightSet = new NodeWeightSet(decreaseNodeWeight(resetNodeWeight(maxSystem)), resetNodeWeight(minSystem));
        } else {
            newNodeWeightSet = new NodeWeightSet(decreaseNodeWeight(maxSystem), minSystem);
        }
        return newNodeWeightSet;
    }
}
